泛型 反射 属性 接口 依赖注入 框架 插件 面向切面编程

倘若我们有一个类,里面有100多个对象,然后要把100多个对象按照顺序保存到CSV中,按照传统方法,我们需要一个一个添加Header,然后拼接对象,组合字符串然后写入文件。

这个样子很累,要非常耐心,要写很久。倘若换了一个类呢,倘若不止100多个呢对象呢,无尽的时间就要为这些杂事所烦恼。

为了解决这个问题,我们可以使用反射,通过类,拿到类内所有的对象元信息,然后通过循环的方案,将这些需要一个个手动的操作转变成自动的操作,于是一个可能几个小时工作量的事情,在使用了反射之后,就可以快速实现。

利用之前泛型的概念,把这个反射的实现封装成一个方法,那么任何对象,直接通过这个方法传入T,就可以实现保存到CSV的结果。

接下来我们更深入一些。

代码中的元数据不是无限制的,一个对象就只有一个属性,那么如果我想要控制某个对象不需要保存到CSV,又或者是他的Herader希望是可以自定义的呢,这也是一个常见的需求,又或者是数据在写入时候希望可以格式化成几位小数,特定的时间格式等等。

为了解决这个问题,语言中为我们提供了特性,有的语言也叫注解,或者属性,通过对对象附加一些信息,让反射在检索的时候,可以拿到这些需要的信息,那么我们就可以扩展之前反射实现的方法,让他更通用一些,操作上更简单一些。

基于这些内容,如果我们已经实现了一些通用的方案,并且实现不依赖于具体的对象,具体的实现可以在后续传入,把这些内容封装在一起,我们就有了基础库,比如Json解析器newsoftjson,一行代码实现类的序列化和反序列化。


先前提到,比如我们有一台相机,封装实现了相机的基础操作,但是后面我们又需要追加对新相机的支持,第二种,第三种,如果通过if else 去实现,非常的累。于是我们会选择抽象出接口。作为基础类型,后续的实现,只要用户自己实现了对于接口的具体实现,那么具体相机如何实现基础操作,和如何使用就部分分离了。

在这个时候,如果A项目需要A相机的支持,但B项目只需要B相机的支持,C项目可能需要A和C相机,我们只需要给他们不同实现模块,那么A项目就不需要又B和C的实现模块。干练方便扩展,易于维护,这就是插件。

如何配置这些模块到具体的使用场景种,我们需要实现一个Manager的管理器通过依赖注入搜索所有的接口并进行管理,还要为这个Manager制作一个管理窗口,一些配置属性和参数信息,那么模块需要配置信息,我们也可以暴漏到Manager中。我们称之为。

同理,不只是相机,电机,函数,串口,菜单,设置等等,可以构建接口的方法,我们都可以这么做。

我们的某一个插件也可以同时实现很多个接口,这样互不影响。

这就是框架的雏形。

我们常用的框架通常内置了许多的接口和方法,我们构建项目的时候,只需要在框架内实现,就可以快速出效果。


为了解决某个具体的问题,我们通常会内置很多个接口去抽象逻辑,比如我们封装的关于相机取图的接口,我们需要在接口前打日志,做异常,检查权限,结束之后,还有处理的方法。

这么一系列的实现,我们在框架下的代码下,去实现的时候,方方面面都需要考虑到,但可以选择性启用或者是不启用,那么这种我们就称之为面向切面编程,具体的框架已经不需要我们去实现,我们只需要给这个已经完善的主题,增加某个具体的实现面,这样代码整体的复杂度使用可控不会出现指数增长。

代码也会非常干净,检查的代码,日志的代码,等等都分离成单独的模块。